/** setycyas自制的表情插件类.用于在任意textarea上方添加表情插件.初始化方法:
 * $textarea:需要使用插件的textarea,$对象;
 * faceTable:一个{},key为表情分类字符串,value是一个列表,列表内容为图片链接;
 * showDebug:布尔值,设定是否显示debug信息.
 * 构造方法不会加入表情包,必须执行main().
 */
class SetycyasFacePlugin {
  
  constructor($textarea,faceTable,showDebug) {
    //复制初始变量
    this._$textarea = $textarea;
    this._faceTable = faceTable;
    this._showDebug = showDebug;

    //设置菜单
    this._$menu = $("<div id=faceMenu></div>");
    this._$menu.css({
      "background-color":"rgb(0,43,54)",
      "line-height":"30px",
      "font-size":"20px",
      "color":"rgb(203,75,22)"
    });
    this._$textarea.before(this._$menu);
    //设置显示图片用的div
    this._$faceDiv = $("<div id=faceContent></div>");
    this._$faceDiv.css({
      "border":"1px solid rgb(131,148,150)",
      "margin-top":"5px",
      "padding":"10px"
    });
    this._$menu.after(this._$faceDiv);
    //FaceSet对象的表,key是FaceSet的name,同时也是this._$menu显示的内容;
    //value则是对应的FaceSet对象
    this._faceSetTable = {};
    //当前显示的表情集合
    this._curFaceSet = null;
  }
  
   /* 显示debug用信息,参数可以多个,像console.log一样使用 */
  debugMsg(){
    if(this._showDebug) {       
      console.log(...arguments);
    }
  }
    
  //往textarea插入文本
  _insertText(textInsert){
    //用数组选择方法把$对象变成一般document对象,访问其光标选择位置
    var pos = this._$textarea[0].selectionEnd;
    // 原文本
    var oldText = this._$textarea.val();
    // 插入完成后的新文本
    var newText = oldText.substr(0,pos)+textInsert+oldText.substr(pos)
    // 插入
    this._$textarea.val(newText);
  }
    
  //初始化菜单与表情table
  _initMenuAndFaces(){
    //再写入菜单需要的html,记录表情集合对象
    var menuHtml = "";
    for(var menuKey in this._faceTable){
      var srcList = this._faceTable[menuKey];
      var objFs = new FaceSet(menuKey,srcList,this._$faceDiv,this._showDebug);
      menuHtml += "<span style=margin-left:30px;>"+menuKey+"</span>";
      this._faceSetTable[menuKey] = objFs;
    }
    this._$menu.html(menuHtml);
  }
    
  /* 绑定所有事件,需要冒泡执行 */
  _addEvents(){
    //添加事件时,需要传入自己,所以要记住自己
    var obj = this;
    //点击菜单,只有点击了'span'标签才生效
    var menu = this._$menu[0];
    menu.addEventListener('click',function(e){
      var target = e.target;
      if(target.tagName.toLowerCase() != 'span'){
        return;
      }
      //点击的文字
      var faceTag = target.textContent;
      //如果当前没有已显示图像集,显示;
      if(!obj._curFaceSet){
        obj._curFaceSet = obj._faceSetTable[faceTag];
        obj._curFaceSet.show();
      }else{
      //若点击的文字不是当前显示的表情集合,把原来的表情集隐藏,显示点击的;
      //否则隐藏当前表情集合.
        if(obj._curFaceSet.getName() == faceTag){
          obj._curFaceSet.hide();
          obj._curFaceSet = null;
        }else{
          obj._curFaceSet.hide();
          obj._curFaceSet = obj._faceSetTable[faceTag];
          obj._curFaceSet.show();
        }
      }
    });
    //点击图片
    var faceDiv = this._$faceDiv[0];
    faceDiv.addEventListener('click',function(e){
      var target = e.target;
      // 点击的不是'img',忽略
      if(target.tagName.toLowerCase() != 'img'){
        return;
      }
      var src = target.src;
      var textInsert = `[img]${src}[/img]`;
      obj._insertText(textInsert);
    });
  }
  
  main(){
    //生成menu与表情集合的具体内容
    this._initMenuAndFaces();
    //绑定事件
    this._addEvents();
  }
}